package com.xxxx.protal.controller;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xxxx.protal.config.AlipayConfig;
import com.xxxx.protal.pojo.Goods;
import com.xxxx.protal.pojo.Order;
import com.xxxx.protal.pojo.OrderGoods;
import com.xxxx.protal.pojo.ResponseCarge;
import com.xxxx.protal.service.IOrderGoodsService;
import com.xxxx.protal.service.IOrderService;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.utils.HttpClientUtils;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author lwf
 * @title: PayController
 * @projectName shop
 * @description: 购物模块 购物车用redis保存
 * @date 2021/1/517:26
 */
@Controller
@RequestMapping("/cart")
@Slf4j
public class PayController {
    //todo 后期认证加入session_id 和user_id这里使用默认值
    private static final String user_id=20+"";
    private static final String session_id="6d7hp7cl7e48ogcln6ktgb4hv7";
   @Resource
   private RedisTemplate<String,Object> redisTemplate;
   @Resource
   private IOrderService orderService;
   @Resource
   private IOrderGoodsService orderGoodsService;
   //首页添加购物车
   @PostMapping("/addCart")
   @ResponseBody
    public Map<String,Object> addCard(Goods goods){
        goods.setAddTime(new Date());
        Map<String,Object> map=new HashMap<>();
        HashOperations<String, Object, Object> ops = redisTemplate.opsForHash();
        ops.put(user_id+session_id,goods.getGoodsId()+"",goods);
        //todo 订单
        map.put("code",200);
        map.put("msg","订单添加"+(ops.hasKey(user_id+session_id,goods.getGoodsId()+"")?"成功":"失败"));
        return map;
    }

   //购物车去
    @GetMapping("/getCartList")
    public String goShopCar(Model model){
        HashOperations<String, Object, Object> ops = redisTemplate.opsForHash();
        Long size = ops.size(user_id+session_id);
        ResponseCarge carge=new ResponseCarge();
        carge.setLength(Math.toIntExact(size));
        List<Object> goods=new ArrayList<>();
        Map<Object, Object> entries = ops.entries(user_id + session_id);
        Double price=0d;
        for(Object one:entries.values()){
            goods.add(one);
            if(((Goods)one).getGoodsNum()!=null){
                price+=((Goods)one).getMarketPrice().doubleValue()*((Goods)one).getGoodsNum();
            }else {
                price+=((Goods)one).getMarketPrice().doubleValue();
            }
        }
        carge.setCartList(goods);
        carge.setTotalPrice(price);
        model.addAttribute("cartResult",carge);
        log.info("购物车");
        log.info(carge.toString());
        return "/cart/list";
    }
    //购物车数量
    @PostMapping("/getCartNum")
    @ResponseBody
    public Long getCartNumber(){
        HashOperations<String, Object, Object> ops = redisTemplate.opsForHash();
        Long size = ops.size(user_id+session_id);
        log.info("购物车大小 = " + size);
        return size;
    }
    //删除一个
    @GetMapping("/delete/{goodsId}")
    public String delete(@PathVariable("goodsId")Integer integer) {
        HashOperations<String, Object, Object> ops = redisTemplate.opsForHash();
        Long delete = ops.delete(user_id + session_id, integer+"");
        log.info("删除一个key:"+integer+",状态："+(delete>1));
        return "redirect:/cart/getCartList";
    }
    //删除全部
    @GetMapping("/delete")
    public String deleteAll() {
       redisTemplate.delete(user_id+session_id);
        return "redirect:/cart/getCartList";
    }
    //购物车物品数量变化
   @PostMapping("/change")
   @ResponseBody
    public Map<String,Object> change(@RequestParam("goodsId") Integer goodsId,@RequestParam("number") Integer number){
      log.info("修改商品"+goodsId+",数量:"+number);
       HashOperations<String, Object, Object> ops = redisTemplate.opsForHash();
       Goods o = (Goods) ops.get(user_id + session_id, goodsId + "");
       o.setGoodsNum(number);
       log.info("删除原数据"+ops.delete(user_id+session_id,goodsId+""));
       log.info(o.toString());
       ops.put(user_id+session_id,goodsId+"",o);
       Map<String,Object> res=new HashMap<>();
       res.put("code",200);
       res.put("total",price());
       log.info("修改订单商品数量返回:"+res.toString());
       return res;
   }
   @Resource
   private SimpleDateFormat simpleDateFormat;
   //去结算
    @GetMapping("/caculate")
    public String goCheck(Model model){
       //添加订单
        Order order=new Order();
        order.setAddTime(Integer.valueOf(simpleDateFormat.format(new Date()).substring(2,11)));
        order.setCountry(1);
        //订单编号
        order.setOrderSn(user_id+session_id);
        order.setUserId(Integer.valueOf(user_id));
        order.setShippingStatus(0);
        order.setPayStatus(0);
        order.setOrderStatus(0);
        order.setPayName("支付宝支付");
        //生成订单，redis中购物车数据加入数据库
        QueryWrapper<Order> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("order_sn",user_id+session_id);
        boolean a=(orderService.count(queryWrapper)==0)?orderService.save(order):false;
        //存在订单
        if(!a){
            model.addAttribute("orderId",orderService.getOne(queryWrapper).getOrderId());
        }else {
            model.addAttribute("orderId",order.getOrderId());
        }
        log.info("订单id:"+order.getOrderId());
        model.addAttribute("total",price());
        HashOperations<String, Object, Object> ops = redisTemplate.opsForHash();
        Map<Object, Object> entries = ops.entries(user_id + session_id);
        Collection<Object> values = entries.values();
        log.info("购物车列表"+values.toString());
        model.addAttribute("orders",values);
       return "/cart/checkCart";
    }
    //支付

    /**
     * 买家账号sodkqa3489@sandbox.com
     * 登录密码111111
     * 支付密码111111
     * 用户名称sodkqa3489
     * 证件类型身份证(IDENTITY_CARD)
     * 证件号码145142199110015648
     * @param request
     * @param response
     * @throws IOException
     * @throws AlipayApiException
     * @throws IOException
     */
    @RequestMapping("/alipay")
    @ResponseBody
    public void payController(HttpServletRequest request, HttpServletResponse response) throws IOException, AlipayApiException, IOException {

        // 获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.APP_ID, AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.sign_type);

        // 设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
        // 商户订单号，商户网站订单系统中唯一订单号，必填
        //防止测试时订单编号重复
        String out_trade_no = request.getParameter("orderId")+(Math.floor(Math.random()*10));
        //更新订单
        Order order=new Order();
        order.setOrderId(Integer.valueOf(request.getParameter("orderId")));
        order.setGoodsPrice(BigDecimal.valueOf(price()));
        order.setPayStatus(1);
        order.setPayTime(Integer.valueOf(simpleDateFormat.format(new Date()).substring(2,11)));
        order.setShippingStatus(1);
        order.setConsignee(request.getParameter("consignee"));
        order.setZipcode(request.getParameter("zipcode"));
        order.setMobile(request.getParameter("mobile"));
        request.getSession().setAttribute("pay",order);
        // 付款金额，必填
       // String total_amount = request.getParameter("total");
        // 订单名称，必填
        String subject = "购物测试数据";
        // 商品描述，可空
        String body =request.getParameter("subject");
        alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
                + "\"total_amount\":\"" +price() + "\","
                + "\"subject\":\"" + subject + "\","
                + "\"body\":\"" + body + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        // 请求
        String form = "";
        try {
            form = alipayClient.pageExecute(alipayRequest).getBody(); // 调用SDK生成表单
            System.out.println("form==>" + form);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        response.setContentType("text/html;charset=" + AlipayConfig.CHARSET);
        response.getWriter().write(form);// 直接将完整的表单html输出到页面
        response.getWriter().flush();
        response.getWriter().close();
    }
    //支付验证
    @RequestMapping("/returnCall")
    public String returnCall(HttpServletRequest request, HttpSession session, Model model) throws Exception {
        request.getParameterMap().forEach((k,v)->{
            System.out.println(k+"-----"+v);
        });
        return "";
    }

    //支付成功跳转
    @RequestMapping("/payFinish")
    public String finish(HttpServletRequest request){
        Order order= (Order) request.getSession().getAttribute("pay");
        orderService.updateById(order);
        log.info(request.getQueryString());
       return "/callback";
    }



    public Double price(){
        //计算总价
        //返回总价
        HashOperations<String, Object, Object> ops = redisTemplate.opsForHash();
        Map<Object, Object> entries = ops.entries(user_id + session_id);
        Double price=0d;
        for(Object one:entries.values()){
            if(((Goods)one).getGoodsNum()!=null){
                price+=((Goods)one).getMarketPrice().doubleValue()*((Goods)one).getGoodsNum();
            }else {
                price+=((Goods)one).getMarketPrice().doubleValue();
            }
        }
        return price;
    }
}
